package com.seeyon.apps.thirdSso.util;

import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.Base64;
import com.seeyon.ctp.util.JDBCAgent;
import com.seeyon.ctp.util.json.JSONUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import shade.okhttp3.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.*;

public class HttpUtils {
    private static Log log = LogFactory.getLog(HttpUtils.class);
    private static final String OPENID_CLIENTID= AppContext.getSystemProperty("thirdSso.OPENID_CLIENTID");
    private static final String OPENID_CLIENTSECRET=AppContext.getSystemProperty("thirdSso.OPENID_CLIENTSECRET");
    private static final String OPENID_REDIRECT_URI=AppContext.getSystemProperty("thirdSso.OPENID_REDIRECT_URI");
    private static final String OPENID_REDIRECT_URI_Mobile=AppContext.getSystemProperty("thirdSso.OPENID_REDIRECT_URI_Mobile");
    private static final String OPENID_KEY=OPENID_CLIENTID+":"+OPENID_CLIENTSECRET;
    private static final String OPENID_URL=AppContext.getSystemProperty("thirdSso.OPENID_URL");

    private static final byte[] OPENID_BASE64= Base64.encode(OPENID_KEY.getBytes(StandardCharsets.UTF_8));
    public static String sendGet(String url) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("text/plain");
//        RequestBody body = RequestBody.create(mediaType, "");
        Request request = new Request.Builder()
                .url(url)
                .method("GET", null)
                .addHeader("Accept", "application/json")
                .addHeader("Content-Type", "application/json")
                .addHeader("Connection", "keep-alive")
                .build();
        Response response = client.newCall(request).execute();
        InputStream soapResponseStream = response.body().byteStream();// 获取返回的流
        byte[] datas = null;
        try {
            datas = readInputStream(soapResponseStream);// 从输入流中读取数据
        } catch (Exception e) {
            e.printStackTrace();
        }
        String result = new String(datas, "UTF-8");
        log.info(result);
        return result;
    }
    /**
     * 从输入流中读取数据
     *
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray();
        outStream.close();
        inStream.close();
        return data;
    }
    public static String getUserInfo(String code,String userAgentFrom){
        //获取token
        Map jo=getOpenidAccessToken(code,userAgentFrom);
        log.info("获取AccessToken："+jo.get("access_token"));
        String access_token = jo.get("access_token")==null?"":String.valueOf(jo.get("access_token"));
        //获取用户信息
        Map userinfo = getUserinfo(access_token);
        String sub = userinfo.get("sub")==null?"":String.valueOf(userinfo.get("sub"));
        if(!sub.contains("|")) {
            log.info("C00001 操作成功，用户无权访问该应用!");
            return null;
        }
        String[] str = sub.split("\\|");
        return str[1];
    }
    //使用code获取Token
    public static Map getOpenidAccessToken(String code,String userAgentFrom){
        log.info("获取AccessToken参数：code:"+code+"Authorization:"+"Basic "+new String(OPENID_BASE64, StandardCharsets.UTF_8));
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Basic "+new String(OPENID_BASE64, StandardCharsets.UTF_8));
        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("grant_type","authorization_code");
        queryParams.put("code",code);
        if (userAgentFrom != null&&"pc".equals(userAgentFrom)){
            log.info("跳转PC:"+OPENID_REDIRECT_URI);
            queryParams.put("redirect_uri",OPENID_REDIRECT_URI);
        }
        if (userAgentFrom != null&&"weixin".equals(userAgentFrom)){
            log.info("跳转H5:"+OPENID_REDIRECT_URI_Mobile);
            queryParams.put("redirect_uri",OPENID_REDIRECT_URI_Mobile);
        }

        String data =  getOpenApi("get",OPENID_URL+"/oauth/token",headers,queryParams,null);
        log.info("获取Token返回信息："+data);
        Map jo= JSONUtil.parseJSONString(data, Map.class);
        return jo;
    }
    //根据token获取用户信息
    public static Map getUserinfo(String accessToken){
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer "+accessToken);
        String data =  getOpenApi("get",OPENID_URL+"/oauth/userinfo",headers,null,null);
        Map jo=JSONUtil.parseJSONString(data,Map.class);
        return jo;
    }
    public static String getOpenApi(String method,String url,Map<String, String> headers,Map<String, String> queryParams,Map<String, Object> bodyMap){
        // 接口的url地址
        StringBuilder u = new StringBuilder(url);
        //拼接queryParam
        if(queryParams!=null){
            if(!queryParams.isEmpty()){
                u.append("?");
                for(String paramKey:queryParams.keySet()){
                    u.append(paramKey+"="+queryParams.get(paramKey)+"&");
                }
            }
        }
        String responseData = "";
        //发送请求
        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder requestBuilder=new Request.Builder().url(u.toString());
        for(String headerKey:headers.keySet()){
            requestBuilder.addHeader(headerKey,headers.get(headerKey));
        }
        if("get".equals(method.toLowerCase(Locale.ROOT))){
            Request request=requestBuilder.build();
            try {
                final Call call = okHttpClient.newCall(request);
                Response response = call.execute();
                responseData = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if("post".equals(method.toLowerCase(Locale.ROOT))){
            String body=bodyMap!=null?JSONUtil.toJSONString(bodyMap):"";
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), body);
            Request request = requestBuilder.post(requestBody).build();
            try {
                final Call call = okHttpClient.newCall(request);
                Response response = call.execute();
                responseData = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
//				System.out.println("请求结果："+responseData);
        log.info("获取用户信息返回信息："+responseData);
        return responseData;
    }
    public static long getMemberIdByCode(String code) {
        JDBCAgent jdbc = null;
        try {
            ArrayList<Object> list = new ArrayList<>();
            String sql = "SELECT ID FROM ORG_MEMBER where CODE =?";
            list.add(code);
            jdbc = new JDBCAgent(true);
            jdbc.execute(sql, list);
            List<Map<String,Object>> resultList = jdbc.resultSetToList();
            if (resultList.size()>0){
                return resultList.get(0).get("id")==null?0:Long.parseLong(resultList.get(0).get("id").toString());
            }
        } catch (BusinessException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally{
            if(jdbc!=null) {
                jdbc.close();
            }
        }
        return 0;
    }

}
